'use strict';
(function(host, name){

var util = '$$$util$$$' in host ? host['$$$util$$$'] : require('./libra.util');

function Controller(fn){
	this.id = util.cache(name, this);
	this.targets = [];
	this.setter = (util.isFunction(fn) ? fn  : function(){}).bind(this);
}
Controller.prototype = {
	defineSetter: function(fn){
		if(util.isFunction(fn)){
			this.setter = fn.bind(this);
		}
	},
	getIndexOfTarget: function(target){
		return this.targets.indexOf(target);
	},
	bind: function(target){
		if(this.getIndexOfTarget(target) < 0){
			this.targets.push(target);
		}
	},
	unbind: function(target){
		var idx = this.getIndexOfTarget(target);
		if(idx > -1){
			this.targets.splice(idx, 1);
		}
	},
	listen: function(val, newVal, model){
		var f = this.setter;
		if(this.targets.length < 1){
			f(null, val, newVal, model, -1);
		} else {
			this.targets.forEach(function(target, i){
				f(target, val, newVal, model, i);
			});
		}
	}
};

Controller.create = function(fn, ctx){
	return new Controller(fn, ctx);
};

Controller.Class = function(name, construct, protos){
	return util.Class(name, Controller, construct, protos);
};

util.regist(host, name, Controller);

})(this, 'controller');